package com.lvyh.lightframe.tracer.core.context.threadlocal;

/*
https://blog.csdn.net/y4x5M0nivSrJaY3X92c/article/details/106416414

Step 1: the main thread obtains the context and passes it to the task for temporary storage.

  All operations after 1 will execute thread operations asynchronously.

Step 2: the asynchronous execution thread takes out the original context and saves it temporarily.
And set the context passed by the main thread.

Step 3: execute asynchronous tasks

Step 4: set the original context back.
 */
public class DelegatingContextRunnable implements Runnable {
    private final Runnable delegate;

    private final String delegateContext;

    public DelegatingContextRunnable(Runnable delegate, String context) {
        assert delegate != null;
        assert context != null;

        this.delegate = delegate;
        this.delegateContext = context;
    }

    public DelegatingContextRunnable(Runnable delegate) {
        // Decorate the original task and save the value of the current thread
        this(delegate, ContextHolder.get());
    }

    public void run() {
        String originalContext = ContextHolder.get();

        try {
            ContextHolder.set(delegateContext);
            delegate.run();
        } finally {
            ContextHolder.set(originalContext);
        }
    }
}
